-- This is a non working version of MD5.
-- I'm working on it, ok?
require("FakeBitOps")
md5 = {}
function md5.computehash(s,raw_mode)
	local message = s
	if not raw_mode == true then
		message = String2Bin(s)
	end
	local r = {
		7,12,17,22,7,12,17,22, 7, 12, 17, 22, 7, 12, 17, 22,
		5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
		4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
		6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
	}
	--Use binary integer part of the sines of integers (Radians) as constants:
	local k = {}
	for i = 0, 63 do
		k[i] = math.floor(math.abs(math.sin(i + 1)) * (2^32))
	end

	--Initialize variables:
	local h0 = Number2Bin(0x67452301)
	local h1 = Number2Bin(0xEFCDAB89)
	local h2 = Number2Bin(0x98BADCFE)
	local h3 = Number2Bin(0x10325476)
	local mlbpp = Endian(ZeroPad(Number2Bin(#message),64,Direction.LEFT)) --message length before preprocessing, little endian.
	print(mlbpp)
	--Pre-processing:
	message = message.."1"
	message = ZeroPad(message,#message+512-(#message%512)-64,Direction.RIGHT)
	message = message..mlbpp

	--Process the message in successive 512-bit chunks:
	for chunk in message:gmatch(string.rep("[01]",512)) do
		local w = {}
		local num = 0
		for c in chunk:gmatch(string.rep("[01]",32)) do
			w[num] = c
			num = num + 1
		end

		--Initialize hash value for this chunk:
		a = h0
		b = h1
		c = h2
		d = h3
		--Main loop:
		for i = 0,63 do
			if 0 >= i and i <= 15 then
				f = Or(And(b,c),(And(Not(b),d)))
				g = i
			elseif 16 >= i and i <= 31 then
				f = Or(And(d,b),And(Not(d),c))
				g = (5*i + 1) % 16
			elseif 32 >= i and i <= 47 then
				f = MultiXor(b,c,d)
				g = (3*i + 5) % 16
			elseif 48 >= i and i <= 63 then
				f = Xor(c,Or(b,Not(d)))
				g = (7*i) % 16
			end
			temp = d
			d = c
			c = b
			b = BinAdd(b,Rotate(MultiBinAdd(a,f,Number2Bin(k[i]),w[g]), r[i-1], Direction.LEFT))
			a = temp
		end
		--Add this chunk's hash to result so far:
		h0 = BinAdd(h0,a)
		h1 = BinAdd(h1,b) 
		h2 = BinAdd(h2,c)
		h3 = BinAdd(h3,d)
	end
	return Bin2Hex(Endian(h0)..Endian(h1)..Endian(h2)..Endian(h3)) --(expressed as little-endian)
end
print(md5.computehash(""))